# -*- coding: utf-8 -*-
# created on 2016/9/23

from mathsolver.functions.base import *
from mathsolver.functions.root.jiefangchenzu import JieFangChenZu
from sympy.abc import x, y, theta
from sympy import S, cos, sqrt, Abs, solveset


# 判断两直线的位置关系
class LinePosLine(BaseFunction):
    def solver(self, *args):
        a1, b1, c1 = args[0].sympify()
        a2, b2, c2 = args[1].sympify()
        if a1 * b2 == a2 * b1:
            if a1 * c2 == a2 * c1:
                self.steps.append(["", "∵(%s) * (%s) = (%s) * (%s) 且 (%s) * (%s) = (%s) * (%s)" %
                                   (new_latex(a1), new_latex(b2), new_latex(a2), new_latex(b1), new_latex(a1),
                                    new_latex(c2),
                                    new_latex(a2), new_latex(c1))])
                self.steps.append(["", "∴ 两直线的位置关系为重合"])
                self.output.append(BaseValue(4))  # 平行 2; 垂直 2; 相交但不垂直 3; 重合 4
            else:
                self.steps.append(["", "∵(%s) * (%s) = (%s) * (%s) 且 (%s) * (%s) != (%s) * (%s)" %
                                   (new_latex(a1), new_latex(b2), new_latex(a2), new_latex(b1), new_latex(a1),
                                    new_latex(c2),
                                    new_latex(a2), new_latex(c1))])
                self.steps.append(["", "∴ 两直线的位置关系为平行"])
                self.output.append(BaseValue(1))
        else:
            if a1 * a2 + b1 * b2 == 0:
                self.steps.append(["", "∵(%s) * (%s) + (%s) * (%s) = 0" %
                                   (new_latex(a1), new_latex(a2), new_latex(b1), new_latex(b2))])
                self.steps.append(["", "∴ 两直线的位置关系为垂直"])
                self.output.append(BaseValue(2))
            else:
                self.steps.append(["", "∵(%s) * (%s) != (%s) * (%s) 且 (%s) * (%s) + (%s) * (%s) != 0" %
                                   (new_latex(a1), new_latex(b2), new_latex(a2), new_latex(b1), new_latex(a1),
                                    new_latex(a2),
                                    new_latex(b1), new_latex(b2))])
                self.steps.append(["", "∴ 两直线的位置关系为相交但不垂直"])
                self.output.append(BaseValue(3))
        self.label.add("判断两直线的位置关系")
        return self


# 根据直线的位置关系列方程或不等式
class LinePosLineParams(BaseFunction):
    def solver(self, *args):
        a1, b1, c1 = args[0].sympify()
        a2, b2, c2 = args[1].sympify()
        text = args[2]
        flag = [0, 0, 0, 0]  # 平行; 垂直; 相交但不垂直; 重合;
        if "平行" in text:
            flag[0] = 1
        elif "垂直" in text:
            flag[1] = 1
        elif "相交" in text:
            flag[2] = 1
        elif "重合" in text:
            flag[3] = 1

        if flag[0] == 1:
            eqs = []
            self.steps.append(["", "由两直线平行,得"])
            self.steps.append(["", "(%s) * (%s) = (%s) * (%s)" % (new_latex(a1), new_latex(b2),
                                                                  new_latex(a2), new_latex(b1))])
            eqs.append([a1 * b2, a2 * b1])
            if a1 * c2 - a2 * c1 != 0:
                self.steps.append(["", "(%s) * (%s) - (%s) * (%s) != 0" % (new_latex(a1), new_latex(c2), new_latex(a2),
                                                                           new_latex(c1))])
                eqs.append([a1 * c2 - a2 * c1, "!=", S.Zero])
            if b1 * c2 - b2 * c1 != 0:
                v = a1 * c2 - a2 * c1
                if v != 0:
                    self.steps.append(
                        ["", "(%s) * (%s) - (%s) * (%s) != 0" % (new_latex(b1), new_latex(c2), new_latex(b2),
                                                                 new_latex(c1))])
                    eqs.append([a1 * c2 - a2 * c1, "!=", S.Zero])
            new_ineqs = []
            for item in eqs:
                if len(item) == 2:
                    ineq = Rel(item[0], item[1])
                    expr = (item[0] - item[1]).expand().simplify()
                else:
                    ineq = Rel(item[0], item[2], item[1])
                    expr = (item[0] - item[2]).expand().simplify()
                expr_freesymbols = expr.free_symbols
                if expr_freesymbols:
                    symbol = list(expr_freesymbols)[0]
                else:
                    symbol = x
                answer = solveset(ineq, symbol, S.Reals)
                if answer != S.Reals:
                    new_ineqs.append(item)
            self.label.add("两直线平行的条件")
            self.output.append(base_gen(new_ineqs))
        elif flag[1] == 1:
            self.steps.append(["", "由两直线垂直,得"])
            self.steps.append(["", "(%s) * (%s) + (%s) * (%s) = 0" % (new_latex(a1), new_latex(a2),
                                                                      new_latex(b1), new_latex(b2))])
            self.steps.append(["", "整理，得"])
            self.steps.append(["", "%s" % BaseEq([a1 * a2 + b1 * b2, S.Zero]).printing()])
            self.output.append(BaseEq([a1 * a2 + b1 * b2, S.Zero]))
            self.label.add("两直线垂直的条件")
        elif flag[2] == 1:
            self.steps.append(["", "由两直线相交,得"])
            self.steps.append(["", "(%s) * (%s) != (%s) * (%s)" % (new_latex(a1), new_latex(b2),
                                                                   new_latex(a2), new_latex(b1))])
            self.output.append(BaseIneq([a1 * b2, "!=", a2 * b1]))
            self.label.add("两直线相交的条件")
        elif flag[3] == 1:
            eqs = []
            self.steps.append(["", "由两直线重合,得"])
            self.steps.append(["", "(%s) * (%s) = (%s) * (%s)" % (new_latex(a1), new_latex(b2),
                                                                  new_latex(a2), new_latex(b1))])
            eqs.append([a1 * b2, a2 * b1])
            if a1 * c2 - a2 * c1 != 0:
                self.steps.append(["", "(%s) * (%s) - (%s) * (%s) != 0" % (new_latex(a1), new_latex(c2), new_latex(a2),
                                                                           new_latex(c1))])
                eqs.append([a1 * c2 - a2 * c1, S.Zero])
            if b1 * c2 - b2 * c1 != 0:
                self.steps.append(["", "(%s) * (%s) - (%s) * (%s) != 0" % (new_latex(b1), new_latex(c2), new_latex(b2),
                                                                           new_latex(c1))])
                eqs.append([a1 * c2 - a2 * c1, S.Zero])
            new_ineqs = []
            for item in eqs:
                if len(item) == 2:
                    ineq = Rel(item[0], item[1])
                    expr = (item[0] - item[1]).expand().simplify()
                else:
                    ineq = Rel(item[0], item[2], item[1])
                    expr = (item[0] - item[2]).expand().simplify()
                expr_freesymbols = expr.free_symbols
                if expr_freesymbols:
                    symbol = list(expr_freesymbols)[0]
                else:
                    symbol = x
                answer = solveset(ineq, symbol, S.Reals)
                if answer != S.Reals:
                    new_ineqs.append(item)
            self.label.add("两直线平行的条件")
            self.output.append(base_gen(new_ineqs))
        return self


# 图像相交列方程组
class GraphIntersection(BaseFunction):
    """
    直线y=2x与直线x+y=3的交点坐标是().
    """
    def solver(self, *args):
        if len(args) == 2:
            f1, f2 = args[0].sympify()
            f3, f4 = args[1].sympify()
            eq1 = [(f1 - f2).simplify(), S.Zero]
            eq2 = [(f3 - f4).simplify(), S.Zero]
        elif len(args) == 1 and isinstance(args[0], BaseZhiXians):
            eq1, eq2 = args[0].sympify()
        self.steps.append(["依题意，得", BaseEqs([eq1, eq2]).printing()])
        stepsolver = JieFangChenZu().solver(BaseEqs([eq1, eq2]), BaseVariables(["x", "y"]))
        self.steps += stepsolver.steps
        self.label.update(stepsolver.label)
        jies = stepsolver.output[0].value2pairs()
        points = []
        for jie in jies:
            jie_keys = list(jie.keys())
            point = {"name": "", "value": [jie[jie_keys[0]], jie[jie_keys[1]]]}
            points.append(point)
        self.steps.append(["", "∴两图像的交点坐标为%s" % (BasePoints(points)).printing()])
        if len(points) == 1:
            self.output.append(BasePoint(points[0]))
        else:
            self.output.append(BasePoints(points))
        self.label.add("求两图像的交点")
        return self


# 求两直线的夹角
class LinesAngle(BaseFunction):
    def solver(self, *args):
        direction_vector1 = args[0].sympify()
        direction_vector2 = args[1].sympify()
        a1 = direction_vector1[0]
        b1 = direction_vector2[1]
        a2 = direction_vector1[0]
        b2 = direction_vector2[1]
        eq_left = cos(theta)
        eq_right = Abs(a1 * a2 + b1 * b2) / (sqrt(a1 ** 2 + b1 ** 2) * sqrt(a2 ** 2 + b2 ** 2))
        self.steps.append(["由直线的夹角公式，可得", BaseEq([eq_left, eq_right]).printing()])
        self.output.append(BaseEq([eq_left, eq_right]))
        self.label.add("求两直线的夹角")
        return self


# 点所在象限，求参
class PointOnAxis(BaseFunction):
    def solver(self, *args):
        if isinstance(args[0], BaseSymbolValue):
            jies = args[0].sympify()
            left = jies[x]
            left_value = left.args[0]
            right = jies[y]
            right_value = right.args[0]
            point = [left_value, right_value]
        else:
            point = args[0].sympify()
        if "第一" in args[1]:
            ineqs = [[point[0], ">", S.Zero], [point[1], ">", S.Zero]]
            self.steps.append(["", "∵ (%s, %s) 在第一象限，则" % (new_latex(point[0]), new_latex(point[1]))])
            self.steps.append(["", BaseIneqs(ineqs).printing()])
            self.output.append(BaseIneqs(ineqs))
        elif "第二" in args[1]:
            ineqs = [[point[0], "<", S.Zero], [point[1], ">", S.Zero]]
            self.steps.append(["", "∵ (%s, %s) 在第二象限，则" % (new_latex(point[0]), new_latex(point[1]))])
            self.steps.append(["", BaseIneqs(ineqs).printing()])
            self.output.append(BaseIneqs(ineqs))
        elif "第三" in args[1]:
            ineqs = [[point[0], "<", S.Zero], [point[1], "<", S.Zero]]
            self.steps.append(["", "∵ (%s, %s) 在第三象限，则" % (new_latex(point[0]), new_latex(point[1]))])
            self.steps.append(["", BaseIneqs(ineqs).printing()])
            self.output.append(BaseIneqs(ineqs))
        elif "第四" in args[1]:
            ineqs = [[point[0], ">", S.Zero], [point[1], "<", S.Zero]]
            self.steps.append(["", "∵ (%s, %s) 在第四象限，则" % (new_latex(point[0]), new_latex(point[1]))])
            self.steps.append(["", BaseIneqs(ineqs).printing()])
            self.output.append(BaseIneqs(ineqs))
        self.label.add("点所在象限的条件")
        return self


# 三直线交于一点
class SanZhiXianYiDian(BaseFunction):
    """
    直线x+ky=0,2x+3y+8=0和x-y-1=0交于一点,则k的值是().
    """
    def solver(self, *args):
        if len(args) == 1:
            eqs = args[0].sympify()
            self.steps.append(["因为三直线交于一点,则", BaseEqs(eqs).printing()])
            eq1 = eqs[0]
            eq2 = eqs[1]
            eq3 = eqs[2]
        elif len(args) == 2:
            eqs = args[0].sympify()
            eq = args[1].sympify()
            eq1 = eqs[0]
            eq2 = eqs[1]
            eq3 = eq
        eq1_symbols = (eq1[0] - eq1[1]).free_symbols
        eq2_symbols = (eq2[0] - eq2[1]).free_symbols
        eq3_symbols = (eq3[0] - eq3[1]).free_symbols
        new_eqs = []
        final_eqs = []
        if eq1_symbols.issubset([x, y]):
            new_eqs.append(eq1)
        else:
            final_eqs.append(eq1)
        if eq2_symbols.issubset([x, y]):
            new_eqs.append(eq2)
        else:
            final_eqs.append(eq2)
        if eq3_symbols.issubset([x, y]):
            new_eqs.append(eq3)
        else:
            final_eqs.append(eq3)
        if len(new_eqs) >= 2 and len(final_eqs) == 1:
            self.steps.append(["先解下列方程", BaseEqs(new_eqs).printing()])
            stepsolver = JieFangChenZu(verbose=True).solver(BaseEqs(new_eqs))
            self.steps += stepsolver.steps
            jie = stepsolver.output[0]
            jie_pairs = jie.value2pairs()
            final_eq = final_eqs[0]
            left = final_eq[0].subs(jie_pairs[0])
            right = final_eq[1].subs(jie_pairs[0])
            self.output.append(BaseEq([left, right]))
        self.label.add("三直线交于同一点问题")
        return self


if __name__ == '__main__':
    pass
